using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;
using Konst3d.Efficiency;
using Konst3d.Efficiency.Suite;
using System.Windows;

// http://pictures.live4fun.ru/joke/514692

namespace PEM
{
	internal partial class MonitoringStatisticViewModel: ViewModelBase
	{
		#region Constants

		private static readonly string[] DAY_LABELS = { "SN", "MN", "TH", "WD", "TH", "FR", "ST" };
		private static readonly Dictionary<MonitorType, string> MONITOR_TYPE_LABELS = new Dictionary<MonitorType, string>();

		#endregion // Constants

		#region Types

		internal delegate void EventHandler(MonitoringStatisticViewModel sender);

		#endregion // Types

		#region Events

		public event EventHandler DaySelected;

		#endregion // Events

		#region Properties

		public IMonitor Monitor
		{
			get
			{
				return _monitor;
			}
		}

		public IEnumerable<IStatisticDay> Statistic
		{
			get
			{
				return _statistic;
			}
		}

		public IStatisticDay Selected
		{
			get
			{
				return _selected;
			}
			set
			{
				_selected = value;

				if (DaySelected != null)
				{
					DaySelected(this);
				}

				NotifyPropertyChanged("Selected");
			}
		}

		public string MonitorActivity
		{
			get
			{
				return _monitor.Active ? "Active" : "Paused";
			}
		}

		public string MonitoringDuration
		{
			get
			{
				return _monitor.Created.GetAge();
			}
		}

		public double RangeScore
		{
			get
			{
				return _rangeScore;
			}
		}

		public double OveralScore
		{
			get
			{
				switch (_monitor.Type)
				{
					case MonitorType.Monitor:
						return _monitor.GetAverageValue();
					case MonitorType.Counter:
						return _monitor.GetSummaryValue();
					case MonitorType.Commandment:
						return _monitor.GetCommandmentViolationsCount();
				}

				return 0;
			}
		}

		public string OveralScoreLabel
		{
			get
			{
				return MONITOR_TYPE_LABELS[_monitor.Type];
			}
		}

		public bool ShowAll
		{
			get
			{
				return _showAll;
			}
			set
			{
				_showAll = value;

				_rangeUpdateInProgress = true;

				StartDate = _monitor.Created;
				EndDate = DateTime.Now;

				_rangeUpdateInProgress = false;

				UpdateStatistic();

				NotifyPropertyChanged("ShowAll");
				NotifyPropertyChanged("RangeSelectionEnabled");
			}
		}

		public bool RangeSelectionEnabled
		{
			get
			{
				return !_showAll;
			}
		}

		public DateTime StartDate
		{
			get
			{
				return _startDate;
			}
			set
			{
				_startDate = value;

				UpdateStatistic();

				NotifyPropertyChanged("StartDate");
			}
		}

		public DateTime EndDate
		{
			get
			{
				return _endDate;
			}
			set
			{
				_endDate = value;

				UpdateStatistic();

				NotifyPropertyChanged("EndDate");
			}
		}

		public CommandsCollection Commands
		{
			get;
			private set;
		}

		#endregion // Properties

		#region Constructors

		public MonitoringStatisticViewModel(IMonitor monitor, Window parentWindow)
		{
			Contract.Requires(monitor != null);
			Contract.Requires(parentWindow != null);

			_monitor = monitor;
			_parentWindow = parentWindow;

			_startDate = DateTime.Now.GetFirstDayOfWeek();
			_endDate = DateTime.Now.GetLastDayOfWeek();

			Commands = new CommandsCollection(this);
			_editDayDlg = new EditStatisticDayDialog();

			UpdateStatistic();
		}

		static MonitoringStatisticViewModel()
		{
			MONITOR_TYPE_LABELS.Add(MonitorType.Monitor, "Overal Efficiency");
			MONITOR_TYPE_LABELS.Add(MonitorType.Counter, "Overal Count");
			MONITOR_TYPE_LABELS.Add(MonitorType.Commandment, "Violations Count");
		}

		#endregion // Constructors

		#region Private Methods

		private void UpdateStatistic()
		{
			if (!_rangeUpdateInProgress)
			{
				var range = _monitor.Statistic.GetRange(_startDate, _endDate);

				_statistic.BeginUpdate();

				_statistic.Clear();

				foreach (var item in range)
				{
					_statistic.Add(item);
				}

				_statistic.EndUpdate();

				_rangeScore = _monitor.Statistic.GetAverageValue(_startDate, _endDate);

				NotifyPropertyChanged("RangeScore");
			}
		}

		#endregion // Private Methods

		#region Fields

		private IMonitor _monitor;
		private bool _showAll;
		private bool _rangeUpdateInProgress;
		private DateTime _startDate;
		private DateTime _endDate;
		private ObservableList2<IStatisticDay> _statistic = new ObservableList2<IStatisticDay>();
		private IStatisticDay _selected;
		private Window _parentWindow;
		private EditStatisticDayDialog _editDayDlg;
		private double _rangeScore;

		#endregion // Fields
	}
}
